﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI.WebControls;
using Wuqi.Webdiyer;
using System.Collections;
using System.Web.UI.HtmlControls;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using COM.Rights.BLL;
using System.Data;


namespace System.Web.UI
{
    public class ZMPageList<TModel> : ZMPageList<BaseBLL<TModel>, TModel>
        where TModel : BaseModel, new()
    { }
    public class ZMPageList<TBLL, TModel> : ZPageList<TModel>
        where TModel : BaseModel, new()
        where TBLL : BaseBLL<TModel>, new()
    {
        protected GridView baseMainGrid = null;
        protected AspNetPager baseMainPager = null;
        protected Panel baseToolBar = null;
        protected Control baseSearchBar = null;
        protected string _Querys = "";
        protected virtual string Querys
        {
            get
            {
                if (string.IsNullOrEmpty(_Querys))
                {
                    Dictionary<string, string> data = new Dictionary<string, string>();
                    foreach (Control control in BaseSearchBar.Controls)
                    {
                        if ((!(control is IButtonControl)) && !string.IsNullOrEmpty(control.ID))
                        {
                            object re = ZBinder.GetControlValue(control);
                            if (re != null)
                                data[control.ID] = re.ToString();
                        }
                    }
                    data["RecordCount"] = RecordCount.Value.ToString();
                    data["PageIndex"] = BaseMainPager.CurrentPageIndex.ToString();
                    data["Sort"] = Sort;
                    data["LastSort"] = LastSort;
                    data["TempSort"] = TempSort;
                    byte[] bytes = CSerialize.Serialize(data);
                    bytes = CCompression.Compress(bytes);
                    string querys = Convert.ToBase64String(bytes);
                    querys = querys.Replace("+", "YIB");
                    _Querys = querys;
                }
                return _Querys;
            }
        }

        protected virtual void InitSearchPageQueryData()
        {
            if (!string.IsNullOrEmpty(Query))
            {
                Dictionary<string, string> data = StringToDictionary(Query);

                foreach (Control control in BaseSearchBar.Controls)
                {
                    if ((!(control is IButtonControl)) && !string.IsNullOrEmpty(control.ID) && data.ContainsKey(control.ID))
                    {
                        ZBinder.BindControl(control, data[control.ID]);
                    }
                }
                if (data.ContainsKey("RecordCount"))
                {
                    RecordCount = Convert.ToInt32(data["RecordCount"]);
                }
                if (data.ContainsKey("PageIndex") && RecordCount.HasValue)
                {
                    BaseMainPager.RecordCount = RecordCount.Value;
                    BaseMainPager.CurrentPageIndex = Convert.ToInt32(data["PageIndex"]);
                }
                if (data.ContainsKey("Sort"))
                {
                    Sort = data["Sort"];
                }
                if (data.ContainsKey("TempSort"))
                {
                    TempSort = data["TempSort"];
                }
                if (data.ContainsKey("LastSort"))
                {
                    LastSort = data["LastSort"];
                }
            }
        }

        protected virtual Dictionary<string, string> StringToDictionary(string str)
        {
            str = str.Replace("YIB", "+");
            byte[] bytes = Convert.FromBase64String(str);
            bytes = CCompression.Decompress(bytes);
            return CSerialize.DeSerialize<Dictionary<string, string>>(bytes);
        }

        protected virtual GridView BaseMainGrid
        {
            get
            {
                RegMainGrid();
                return baseMainGrid;
            }
        }
        protected virtual AspNetPager BaseMainPager
        {
            get
            {
                RegAspNetPager();
                return baseMainPager;
            }
        }
        protected Panel BaseToolBar
        {
            get
            {
                RegToolBar();
                return baseToolBar;
            }
        }

        protected Control BaseSearchBar
        {
            get
            {
                RegSearchBar();
                return baseSearchBar;
            }
        }

        protected virtual void RegMainGrid()
        {
            if (baseMainGrid == null)
            {
                if (Master != null)
                {
                    switch (ZConfig.TemplateLayer)
                    {
                        case 1:
                            baseMainGrid = (GridView)Page.Master.Master.FindControl("contentPlaceHolder").FindControl("contentPlaceHolder").FindControl("gvInfos");
                            break;
                        case 2:
                            baseMainGrid = (GridView)Page.Master.Master.Master.FindControl("contentPlaceHolder").FindControl("contentPlaceHolder").FindControl("contentPlaceHolder").FindControl("gvInfos");
                            break;
                        default:
                            baseMainGrid = (GridView)Page.Master.Master.FindControl("contentPlaceHolder").FindControl("contentPlaceHolder").FindControl("gvInfos");
                            break;
                    }
                }
                else
                    baseMainGrid = Page.FindControl("gvInfo") as GridView;
            }
        }
        protected virtual void RegAspNetPager()
        {
            if (baseMainPager == null)
            {
                if (Master != null)
                {
                    switch (ZConfig.TemplateLayer)
                    {
                        case 1:
                            baseMainPager = (AspNetPager)Page.Master.Master.FindControl("contentPlaceHolder").FindControl("pager");
                            break;
                        case 2:
                            baseMainPager = (AspNetPager)Page.Master.Master.Master.FindControl("contentPlaceHolder").FindControl("contentPlaceHolder").FindControl("pager");
                            break;
                        default:
                            baseMainPager = (AspNetPager)Page.Master.Master.FindControl("contentPlaceHolder").FindControl("pager");
                            break;
                    }
                }
                else
                    baseMainPager = Page.FindControl("pager") as AspNetPager;
            }
        }
        protected virtual void RegToolBar()
        {
            if (baseToolBar == null)
            {
                if (Master != null)
                {
                    switch (ZConfig.TemplateLayer)
                    {
                        case 1:
                            baseToolBar = (Panel)Page.Master.Master.FindControl("contentPlaceHolder").FindControl("toolBar");
                            break;
                        case 2:
                            baseToolBar = (Panel)Page.Master.Master.Master.FindControl("contentPlaceHolder").FindControl("contentPlaceHolder").FindControl("toolBar");
                            break;
                        default:
                            baseToolBar = (Panel)Page.Master.Master.FindControl("contentPlaceHolder").FindControl("toolBar");
                            break;
                    }
                }
                else
                    baseToolBar = Page.FindControl("toolBar") as Panel;
            }
        }
        protected virtual void RegSearchBar()
        {
            if (baseSearchBar == null)
            {
                if (Master != null)
                {
                    switch (ZConfig.TemplateLayer)
                    {
                        case 1:
                            baseSearchBar = (Control)Page.Master.Master.FindControl("contentPlaceHolder").FindControl("contentPlaceHolderToolBar");
                            break;
                        case 2:
                            baseSearchBar = (Control)Page.Master.Master.Master.FindControl("contentPlaceHolder").FindControl("contentPlaceHolder").FindControl("contentPlaceHolderToolBar");
                            break;
                        default:
                            baseSearchBar = (Control)Page.Master.Master.FindControl("contentPlaceHolder").FindControl("contentPlaceHolderToolBar");
                            break;
                    }
                }
                else
                    baseSearchBar = Page.FindControl("contentPlaceHolderToolBar") as Panel;
            }
        }

        protected override void RegListControls()
        {
            InitToolBar();
        }
        protected virtual void InitToolBar()
        {
            InitBtnSearch();
            InitBtnDelete();
            InitBtnAdd();
            //InitBtnSave();
            InitExcel();
        }
        protected virtual void InitBtnSearch()
        {
            ImageButton ibtnSearch = new ImageButton();
            ibtnSearch.ID = "ToolBarSearch";
            ibtnSearch.ImageUrl = ZPath.ImagesURI + "ToolBar" + GetLanguage() + "ImgSearch.GIF";
            ibtnSearch.Click += new ImageClickEventHandler(ToolBarSearchClick);
            BaseToolBar.Controls.Add(ibtnSearch);
        }
        protected virtual void InitBtnDelete()
        {
            ImageButton ibtnDelete = new ImageButton();
            ibtnDelete.ID = "ToolBarDelete";
            ibtnDelete.ImageUrl = ZPath.ImagesURI + "ToolBar" + GetLanguage() + "ImgDelete.GIF";
            ibtnDelete.OnClientClick = "return MyConfirm();";
            ibtnDelete.Click += new ImageClickEventHandler(ToolBarDeleteClick);
            BaseToolBar.Controls.Add(ibtnDelete);
        }
        protected virtual void InitBtnAdd()
        {
            ImageButton ibtnAdd = new ImageButton();
            ibtnAdd.ID = "ToolBarAdd";
            ibtnAdd.ImageUrl = ZPath.ImagesURI + "ToolBar" + GetLanguage() + "ImgAdd.GIF";
            ibtnAdd.OnClientClick = "return GoEdit();";
            BaseToolBar.Controls.Add(ibtnAdd);
        }
        protected virtual void InitBtnSave()
        {
            ImageButton ibtnSave = new ImageButton();
            ibtnSave.ID = "ToolBarSave";
            ibtnSave.ImageUrl = ZPath.ImagesURI + "ToolBar" + GetLanguage() + "ImgSave.GIF";
            ibtnSave.Click += new ImageClickEventHandler(ToolBarSaveClick);
            BaseToolBar.Controls.Add(ibtnSave);
        }

        private void InitExcel()
        {
            ImageButton ibtnExcel = new ImageButton();
            ibtnExcel.ID = "ToolBarExcel2";
            ibtnExcel.ImageUrl = ZPath.ImagesURI + "ToolBar" + GetLanguage() + "ImgExcel.GIF";
            ibtnExcel.Click += new ImageClickEventHandler(OnExcelClick);
            BaseToolBar.Controls.Add(ibtnExcel);
        }

        protected virtual string[,] ExcelHeader
        {
            get
            {
                return null;
            }
        }

        protected virtual void OnExcelClick(object sender, ImageClickEventArgs e)
        {
            if (BaseMainGrid != null)
            {
                ExportExcel.PrepareGridViewForExport(BaseMainGrid);
                ExportExcel.ExportGridView(BaseMainGrid, "Data" + DateTime.Now.ToString("yyyyMMddHHmmss").Replace("-", ""));
            }
        }

        protected virtual void ToolBarSaveClick(object sender, ImageClickEventArgs e)
        {

        }
        protected virtual void ToolBarSearchClick(object sender, ImageClickEventArgs e)
        {
            OnBtnSearchClick(sender, e);
        }
        protected virtual void ToolBarDeleteClick(object sender, ImageClickEventArgs e)
        {
            string str = "";
            foreach (string s in GetCheckedList())
            {
                str += "'" + s + "',";
            }
            str = str.Trim(',');
            if (!string.IsNullOrEmpty(str))
            {
                TBLL bll = new TBLL();
                if (bll.IsLogicDelete)
                {
                    BdOperateLog bol = new BdOperateLog();
                    bol.OperateLog(ZASession.Account, str, bll.TableName, "批量删除");

                    str = (new TModel()).GetPrimaryKey() + " IN (" + str + ")";
                    bll.Update("IsDelete", str, true, new List<DBParameter>());
                    //记录日志

                }
                else
                {
                    str = (new TModel()).GetPrimaryKey() + " IN (" + str + ")";
                    bll.Delete(str, new List<DBParameter>());
                }
                

                OnGridChanged();
            }

        }

        //protected void OperateLog(string OperateBy, string IDS, string TableName, string OperateType)
        //{
        //    List<DBParameter> _listDBParameter = new List<DBParameter>();
        //    _listDBParameter.Add(new DBParameter("@TranType", "Save"));
        //    _listDBParameter.Add(new DBParameter("@OperateBy", OperateBy));
        //    _listDBParameter.Add(new DBParameter("@IDS", IDS));
        //    _listDBParameter.Add(new DBParameter("@TableName", TableName));
        //    _listDBParameter.Add(new DBParameter("@OperateType", OperateType));
            
        //    bol.ExecuteNonQuery("[dbo].[bdOperateLog_Save]", _listDBParameter, System.Data.CommandType.StoredProcedure);

        //}

        protected virtual DataTable MainDateTable
        {
            get { return (DataTable)ViewState["_dtGridView"]; }
            set { ViewState["_dtGridView"] = value; }
        }

        protected override void SetControlsProperty()
        {
            base.SetControlsProperty();
            SetGridViewProperty(BaseMainGrid);

            TModel t = new TModel();
            string primaryKey = t.GetPrimaryKey();

            if (BaseMainGrid != null)
            {
                if (!string.IsNullOrEmpty(primaryKey))
                    BaseMainGrid.DataKeyNames = new string[] { primaryKey };
            }

            if (BaseMainGrid != null)
            {
                if (!string.IsNullOrEmpty(primaryKey))
                    BaseMainGrid.DataKeyNames = new string[] { primaryKey };
            }

        }
        protected override void RegListControlsEvent()
        {
            if (BaseMainGrid != null)
            {
                BaseMainGrid.Sorting += new GridViewSortEventHandler(OnMainGridSorting);
                BaseMainGrid.RowDataBound += new GridViewRowEventHandler(OnMainGridRowDataBound);
                BaseMainGrid.RowCancelingEdit += new GridViewCancelEditEventHandler(OnMainGridRowCancelingEdit);
                BaseMainGrid.RowEditing += new GridViewEditEventHandler(OnMainGridRowEditing);
                BaseMainGrid.RowUpdating += new GridViewUpdateEventHandler(OnMianGridRowUpdating);
                BaseMainGrid.RowDeleting += new GridViewDeleteEventHandler(OnMainGridRowDeleting);
                BaseMainGrid.RowCommand += new GridViewCommandEventHandler(OnMainGridRowCommand);
            }
            if (BaseMainPager != null)
                BaseMainPager.PageChanged += new EventHandler(OnPagerPageChanged);
        }
        protected virtual void OnMainGridRowCommand(object sender, GridViewCommandEventArgs e)
        {

        }
        protected virtual void OnBtnSearchClick(object sender, EventArgs e)
        {
            RecordCount = -1;
            BaseMainPager.CurrentPageIndex = 0;
            OnGridChanged();
        }
        protected virtual void OnSearchInputInit(ref string val, ref string opt, string field)
        {

        }
        protected virtual void OnSearchInputInited(ref string val, ref string opt, string field)
        {

        }
        protected virtual void InitFilter()
        {
            if (!IsPostBack)
                InitSearchPageQueryData();
            DBParameters.Clear();
            Filter = DefaultFilter;
            foreach (Control con in BaseSearchBar.Controls)
            {
                string val = "";
                string opt = "";
                string field = "";
                string isMaxDate = "";
                if (con is IAttributeAccessor)
                {
                    IAttributeAccessor htmlControl = (IAttributeAccessor)con;
                    opt = htmlControl.GetAttribute("Opt");
                    field = htmlControl.GetAttribute("Field");
                    isMaxDate = htmlControl.GetAttribute("IsMaxDate");
                    if (string.IsNullOrEmpty(field) || string.IsNullOrEmpty(opt))
                        continue;
                }
                else { continue; }
                if (con is ITextControl)
                {
                    val = ((ITextControl)con).Text;
                }
                if (con is ListControl)
                {
                    val = ((ListControl)con).SelectedValue;
                }
                if (con is ICheckBoxControl)
                {
                    val = ((ICheckBoxControl)con).Checked.ToString();
                }
                if (string.IsNullOrEmpty(val))
                    continue;
                if (!string.IsNullOrEmpty(isMaxDate) && isMaxDate == "true")
                {
                    val = Convert.ToDateTime(val).AddDays(1).ToString("yyyy-MM-dd");
                }
                if (field.IndexOf(",") > 0)
                {
                    List<DBParameter> dpss;
                    Filter += GetFilter(field, con.ClientID, out dpss, opt, val, con);
                    DBParameters.AddRange(dpss);
                }
                else
                {
                    Filter += InitFilter(ref val, opt, field, con.ClientID, "AND", con, DBParameters);
                }

            }
        }
        protected virtual string InitFilter(ref string val, string opt, string field, string conID, string sqlOpt, Control con, List<DBParameter> dps)
        {
            string result = "";
            OnSearchInputInit(ref val, ref opt, field);
            if (opt != "%")
                result = " " + sqlOpt + " ([" + field + "]" + opt + "@" + conID + field + ")";
            else
                result = " " + sqlOpt + " ([" + field + "] LIKE '%' + @" + conID + field + " + '%')";
            dps.Add(new DBParameter(conID + field, val));
            OnSearchInputInited(ref val, ref opt, field);
            return result;
        }

        private string GetFilter(string fields, string conID, out List<DBParameter> dps, string opt, string val, Control con)
        {
            string[] fieldss = fields.Split(',');
            string result = "";
            dps = new List<DBParameter>();
            foreach (string field in fieldss)
            {
                result += InitFilter(ref val, opt, field, conID, "OR", con, dps);
            }
            result = result.Trim().Trim('O').Trim('R').Trim();
            result = " AND (" + result + ")";
            return result;

        }
        protected virtual void OnMainGridRowDataBound(object sender, GridViewRowEventArgs e)
        {
            if (e.Row.RowType == DataControlRowType.DataRow)
            {
                e.Row.Attributes.Add("onmouseover", "currentcolor = this.style.backgroundColor;this.style.backgroundColor='#afd6f5';");
                e.Row.Attributes.Add("onmouseout", "this.style.backgroundColor = currentcolor;");
                foreach (Control control in e.Row.Controls)
                {
                    if (control.Controls.Count > 0)
                    {
                        Control col = control.Controls[0];
                        if (col is HyperLink)
                        {
                            HyperLink hy = col as HyperLink;
                            //hy.NavigateUrl = hy.NavigateUrl + "&Query=" + Querys;
                            hy.NavigateUrl = hy.NavigateUrl;
                        }
                    }
                }
            }

        }
        protected virtual void OnPagerPageChanged(object sender, EventArgs e)
        {
          //  IsPaging = true;
            OnGridChanged();
        }
        protected virtual void OnMainGridSorting(object sender, GridViewSortEventArgs e)
        {
            string sortField = e.SortExpression;
            string sortType = "DESC";
            string sort = sortField + " " + sortType;
            if (Sort != null)
            {
                if (Sort.IndexOf("DESC") >= 0)
                    sort = sortField + " ASC";
            }
            Sort = sort;
            IsSortChanging = true;
            OnGridChanged();
        }
        protected virtual void OnMainGridRowDeleting(object sender, GridViewDeleteEventArgs e)
        {
            OnMainGridRowDeleting(e);
            OnGridChanged();
        }
        protected virtual void OnMainGridRowDeleting(GridViewDeleteEventArgs e)
        {
            OnMainGridRowDeletingTMethod<TBLL, TModel>(e);
        }
        protected virtual void OnMainGridRowDeletingTMethod<TB, T>(GridViewDeleteEventArgs e)
            where T : BaseModel, new()
            where TB : BaseBLL<T>, new()
        { 
            /*保存删除日期*/
            //ZASession.Account;
            
            string id = BaseMainGrid.DataKeys[e.RowIndex].Value.ToString();

            TB bll = new TB();

            if (bll.IsLogicDelete) {
                bll.Update("IsDelete", string.Format("{0}='{1}'", bll.PrimaryKey, id), true, new List<DBParameter>());
                //记录日志
                BdOperateLog bol = new BdOperateLog();
                bol.OperateLog(ZASession.Account, id, bll.TableName, "单笔删除");
            }
            else {
                bll.Delete(id);  
            }
           
            bll.Dispose();
        }
        protected virtual void OnMainGridRowEditing(object sender, GridViewEditEventArgs e)
        {
            BaseMainGrid.EditIndex = e.NewEditIndex;
            OnGridChanged();
        }
        protected virtual void OnMainGridRowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
        {
            BaseMainGrid.EditIndex = -1;
            OnGridChanged();
        }
        protected virtual void OnMianGridRowUpdating(object sender, GridViewUpdateEventArgs e)
        {
            OnMianGridRowUpdating(e);
            BaseMainGrid.EditIndex = -1;
            OnGridChanged();
        }

        protected virtual void OnMianGridRowUpdating(GridViewUpdateEventArgs e)
        {
            OnMianGridRowUpdatingTMethod<TBLL, TModel>(e);
        }

        protected virtual void OnMianGridRowUpdatingTMethod<TB, T>(GridViewUpdateEventArgs e)
            where T : BaseModel, new()
            where TB : BaseBLL<T>, new()
        {
            string id = BaseMainGrid.DataKeys[e.RowIndex].Value.ToString();

            T model = new T();
            CModel.SetProValue(model, model.GetPrimaryKey(), id);
            model.SetIsNew(false);

            foreach (DictionaryEntry de in e.NewValues)
            {
                CModel.SetProValue(model, de.Key.ToString(), de.Value);
            }

            BindMainGridUpdateRowToModel<T>(model, this.BaseMainGrid.Rows[e.RowIndex]);

            TB bll = new TB();
            bll.InsertOrUpdate(model, "*");
        }

        protected override void OnGridDataBinding()
        {
            base.OnGridDataBinding();

            if (ZSetup.IFUseLanguage)
            {
                foreach (DataControlField field in BaseMainGrid.Columns)
                {
                    field.HeaderText = ZLanguages.GetLanguages(field.HeaderText);
                    if (field is CommandField)
                    {
                        CommandField cfield = field as CommandField;
                        cfield.CancelText = ZLanguages.GetLanguages("App_Cancel");
                        cfield.EditText = ZLanguages.GetLanguages("App_Edit");
                        cfield.UpdateText = ZLanguages.GetLanguages("App_Update");
                    }
                    if (field is HyperLinkField)
                    {
                        HyperLinkField hField = field as HyperLinkField;
                        if (hField.Text.StartsWith("App_"))
                        {
                            hField.Text = ZLanguages.GetLanguages(hField.Text);
                        }
                    }
                }
            }
        }
        protected override void OnGridDataBind()
        {
            InitFilter();

            TBLL bll = new TBLL();

            BaseMainPager.PageSize = PageSize;

            int? recordCount = RecordCount;
            List<TModel> infos = null;

            int? iPageIndex = BaseMainPager.CurrentPageIndex;
            int? iPageSize = BaseMainPager.PageSize;

            List<DBParameter> dbs = new List<DBParameter>();
            foreach (DBParameter db in DBParameters)
            {
                dbs.Add(db);
            }
            infos = bll.GetList(iPageIndex, iPageSize, ref recordCount, Columns, Filter, GetSort(), dbs);

            BaseMainGrid.DataSource = infos;
            BaseMainGrid.DataBind();

            BaseMainPager.RecordCount = recordCount.Value;
            RecordCount = recordCount;

            bll.Dispose();

        }
        protected virtual void BindMainGridUpdateRowToModel<T>(T model, Control control)
        {
            ZBinder.BindControlsToModel<T>(model, control);
        }
        protected virtual void BindMainGridAddRowToModel<T>(T model, Control control)
        {
            ZBinder.BindControlsToModel<T>(model, control);
        }
        protected virtual List<string> GetCheckedList()
        {
            List<string> checkedList = new List<string>();

            for (int i = 0; i < BaseMainGrid.Rows.Count; i++)
            {
                if (BaseMainGrid.Rows[i].RowType == DataControlRowType.DataRow)
                {
                    if (BaseMainGrid.Rows[i].FindControl("cbItem") != null)
                    {
                        Control ck = BaseMainGrid.Rows[i].FindControl("cbItem");
                        if (ck is HtmlInputCheckBox)
                        {
                            HtmlInputCheckBox cb = ck as HtmlInputCheckBox;
                            if (cb.Checked)
                                checkedList.Add(BaseMainGrid.DataKeys[i][0].ToString());
                            ForeachGridDataRow(cb.Checked, BaseMainGrid.Rows[i], i);
                        }
                        if (ck is CheckBox)
                        {
                            CheckBox cb = ck as CheckBox;
                            if (cb.Checked)
                                checkedList.Add(BaseMainGrid.DataKeys[i][0].ToString());
                            ForeachGridDataRow(cb.Checked, BaseMainGrid.Rows[i], i);
                        }
                    }
                }
                ForeachGridRow(BaseMainGrid.Rows[i]);
            }
            return checkedList;
        }

        protected virtual void ForeachGridRow(GridViewRow row)
        {

        }
        protected virtual void ForeachGridDataRow(bool isChecked, GridViewRow row)
        {

        }

        protected virtual void ForeachGridDataRow(bool isChecked, GridViewRow row, int index)
        {

        }
    }
}
